package server;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.regex.Matcher;

/**
 * @author xsl
 * @date 2021/2/20 17:42
 * @Description: Catalina
 */
public class Catalina {

    protected String configFile = "server.xml";

    private int serverPort = -1;

    private Mapper.MappedHost mappedHost;

    public void load() {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(configFile);
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();
            Element service = (Element) rootElement.selectSingleNode("//Service");
            Element connector = (Element) service.selectSingleNode("//Connector");
            //解析出监听的端口号
            serverPort = Integer.valueOf(connector.attribute("port").getValue());
            Element engine = (Element) service.selectSingleNode("//Engine");
            Element host = (Element) engine.selectSingleNode("//Host");
            //解析出Host名称
            String hostName = host.attributeValue("name");
            String appBase = host.attributeValue("appBase");
            File file = new File(appBase);
            String[] fileList = file.list();
            File webDemo;
            File webInfo;
            File webXml;
            Mapper.MappedContext[] contexts = new Mapper.MappedContext[fileList.length];
            int i = 0;
            for (String fileName : fileList) {
                webDemo = new File(file.getAbsolutePath(), fileName);
                String webInfoName = webDemo.list()[1];
                webInfo = new File(webDemo.getAbsolutePath(), webInfoName);
                webXml = new File(webInfo.getAbsolutePath(), "web.xml");
                FileInputStream fileInputStream = new FileInputStream(webXml);
                Mapper.MappedWrapper[] mappedWrappers = loadServlet(fileInputStream, webInfo.getAbsolutePath() + "\\classes");
                Mapper.MappedContext mappedContext = new Mapper.MappedContext(fileName, mappedWrappers);
                contexts[i] = mappedContext;
                i++;
            }
            Mapper.ContextList contextList = new Mapper.ContextList(contexts);
            //初始化 MappedHost
            mappedHost = new Mapper.MappedHost(hostName, contextList);
            System.out.println("1111111111111:" + contextList.contexts.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 加载解析web.xml，初始化Servlet
     */
    private Mapper.MappedWrapper[] loadServlet(FileInputStream resourceAsStream, String path) {

        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(resourceAsStream);
            Element rootElement = document.getRootElement();

            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            Mapper.MappedWrapper[] mappedWrappers = new Mapper.MappedWrapper[selectNodes.size()];
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element = selectNodes.get(i);
                // <servlet-name>lagou</servlet-name>
                Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletnameElement.getStringValue();
                // <servlet-class>server.LagouServlet</servlet-class>
                Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                String servletClass = servletclassElement.getStringValue();
                System.out.println("servletClass:" + servletClass);
                // 根据servlet-name的值找到url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                // /lagou
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                MyClassLoader classLoader = new MyClassLoader(path + "\\");
                Class clazz = classLoader.loadClass(servletClass);
                HttpServlet httpServlet = (HttpServlet) clazz.newInstance();
                Wrapper wrapper = new ServletWrapper(httpServlet);
                Mapper.MappedWrapper mappedWrapper = new Mapper.MappedWrapper(urlPattern, wrapper);
                mappedWrappers[i] = mappedWrapper;
            }
            return mappedWrappers;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public int getServerPort() {
        return serverPort;
    }

    public Mapper.MappedHost getMappedHost() {
        return mappedHost;
    }
}
